package controller

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"log"
	"net/http"
	"server/common"
	"server/model"
	"server/response"
	"server/vo"
	"strconv"
)

type IPostController interface {
	RestController
	ShowMyArticles(ctx *gin.Context)
	PageList(ctx *gin.Context)
	Column(ctx *gin.Context)
	IncreaseLikes(ctx *gin.Context)
	SearchArticles(ctx *gin.Context)
}

type PostController struct {
	DB *gorm.DB
}

func (p PostController) Create(ctx *gin.Context) {
	var requestPost vo.CreatePostRequest
	// 数据验证
	if err := ctx.ShouldBind(&requestPost); err != nil {
		log.Print(err.Error())
		response.Fail(ctx, "数据验证错误", nil)
		return
	}

	// 获取登录用户
	user, _ := ctx.Get("user")

	// 创建post
	post := model.Post{
		UserId:     user.(model.User).ID,
		UserName:   user.(model.User).Name,
		CategoryId: requestPost.CategoryId,
		Title:      requestPost.Title,
		HeadImg:    requestPost.HeadImg,
		Content:    requestPost.Content,
	}

	// 插入数据
	if err := p.DB.Create(&post).Error; err != nil {
		panic(err)
		return
	}

	// 成功
	response.Success(ctx, nil, "创建成功")
}

func (p PostController) Update(ctx *gin.Context) {
	var requestPost vo.CreatePostRequest
	// 数据验证
	if err := ctx.ShouldBind(&requestPost); err != nil {
		log.Print(err.Error())
		response.Fail(ctx, "数据验证错误", nil)
		return
	}

	// 获取path中的id
	postId := ctx.Params.ByName("id")

	var post model.Post
	if p.DB.Where("id = ?", postId).First(&post).RecordNotFound() {
		response.Fail(ctx, "文章不存在", nil)
		return
	}

	// 判断当前用户是否为文章的作者
	// 获取登录用户
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID
	if userId != post.UserId {
		response.Fail(ctx, "文章不属于您，请勿非法操作", nil)
		return
	}

	// 更新文章
	if err := p.DB.Model(&post).Update(requestPost).Error; err != nil {
		response.Fail(ctx, "更新失败", nil)
		return
	}
	response.Success(ctx, gin.H{"post": post}, "更新成功")
}

func (p PostController) Show(ctx *gin.Context) {
	// 获取path中的id
	postId := ctx.Params.ByName("id")
	var post model.Post
	if p.DB.Preload("Category").Preload("LikeList", "post_id = ?", postId).Where("id = ?", postId).First(&post).RecordNotFound() {
		response.Fail(ctx, "文章不存在", nil)
		return
	}
	var stars int
	p.DB.Model(model.Like{}).Where("post_id = ?", postId).Count(&stars)
	response.Success(ctx, gin.H{"post": post, "stars": stars}, "成功")
}

func (p PostController) Delete(ctx *gin.Context) {
	// 获取path中的id
	postId := ctx.Params.ByName("id")
	var post model.Post
	if p.DB.Where("id = ?", postId).First(&post).RecordNotFound() {
		response.Fail(ctx, "文章不存在", nil)
		return
	}
	// 判断当前用户是否为文章的作者
	// 获取登录用户
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID
	if userId != post.UserId {
		response.Fail(ctx, "文章不属于您，请勿非法操作", nil)
		return
	}
	p.DB.Delete(&post)
	response.Success(ctx, gin.H{"post": post}, "删除成功")
}

// @Title 文章列表
// @Tags 文章API
// @Accept json
// @Summary 文章列表接口
// @Description 获取数据库中所有文章
// @Produce  json
// @Param pageNum query int64 false "页码"
// @Param pageSize query int64 false "每页数量"
// @Success 200 {string} string  "ok"
// @Router /page/list [post]
func (p PostController) PageList(ctx *gin.Context) {

	// 获取分页参数
	pageNum, _ := strconv.Atoi(ctx.DefaultQuery("pageNum", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))

	// 分页
	var posts []model.Post
	p.DB.Preload("Category").Order("created_at desc").Offset((pageNum - 1) * pageSize).Limit(pageSize).Find(&posts)

	// 记录的总条数
	var total int
	p.DB.Model(model.Post{}).Count(&total)

	// 返回数据
	response.Success(ctx, gin.H{"data": posts, "total": total}, "成功")
}

// @Summary 我的文章接口
// @Tags 文章API
// @Description 获取当前登录用户发布的文章
// @Param Authorization	header string true "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTYzOTk4MzkyNywiaWF0IjoxNjM5Mzc5MTI3LCJpc3MiOiJ0ZXN0Iiwic3ViIjoidXNlciB0b2tlbiJ9.4bdcjtAmK9ItuN7iuyMfFMu24fK6-4kPtsIyxEGbHAw"
// @Success 200 {string} string  "ok"
// @Router /MyArticles [get]
func (p PostController) ShowMyArticles(ctx *gin.Context) {
	//获取登录用户
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID
	var posts []model.Post
	p.DB.Preload("Category").Where("user_id = ?", userId).Order("created_at desc").Find(&posts)
	// 记录的总条数
	var total int
	p.DB.Model(model.Post{}).Where("user_id = ? ", userId).Count(&total)
	// 返回数据
	response.Success(ctx, gin.H{"data": posts, "total": total}, "成功")

}

func (p PostController) Column(ctx *gin.Context) {
	pageNum, _ := strconv.Atoi(ctx.DefaultQuery("pageNum", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))
	categoryName := ctx.Params.ByName("name")

	var category model.Category
	p.DB.Where("name = ?", categoryName).First(&category)

	var posts []model.Post
	p.DB.Preload("Category").Where("category_id = ?", category.ID).Order("created_at desc").Offset((pageNum - 1) * pageSize).Limit(pageSize).Find(&posts)

	// 记录的总条数
	var total int
	p.DB.Model(model.Post{}).Where("category_id = ?", category.ID).Count(&total)

	// 返回数据
	response.Success(ctx, gin.H{"data": posts, "total": total}, "成功")

}

func (p PostController) IncreaseLikes(ctx *gin.Context) {
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID
	username := user.(model.User).Name
	postId := ctx.Params.ByName("id")

	var total int
	p.DB.Model(model.Like{}).Where("user_id = ? AND post_id = ?", userId, postId).Count(&total)
	if total == 0 {
		like := model.Like{
			UserId:   userId,
			UserName: username,
			PostId:   postId,
		}

		if err := p.DB.Create(&like).Error; err != nil {
			panic(err)
			return
		}
		var post model.Post

		if err := p.DB.Model(&post).Where("id = ?", postId).Update("stars", gorm.Expr("stars + 1")).Error; err != nil {
			response.Fail(ctx, "点赞失败", nil)
			return
		}
		// 成功
		response.Success(ctx, nil, "点赞成功")

	} else {
		response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "已经点赞过了")
		return
	}

}

func (p PostController) SearchArticles(ctx *gin.Context) {
	// 获取分页参数
	pageNum, _ := strconv.Atoi(ctx.DefaultQuery("pageNum", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))

	Title := ctx.Params.ByName("title")

	var posts []model.Post
	p.DB.Preload("Category").Where("title like ?", "%"+Title+"%").Order("created_at desc").Offset((pageNum - 1) * pageSize).Limit(pageSize).Find(&posts)

	var total int
	p.DB.Model(model.Post{}).Where("title like ?", "%"+Title+"%").Count(&total)
	response.Success(ctx, gin.H{"data": posts, "total": total}, "成功")
}

func NewPostController() IPostController {
	db := common.GetDB()
	db.AutoMigrate(model.Post{}, model.Like{})
	return PostController{DB: db}
}
